iT邦幫忙

2024 iThome 鐵人賽

DAY 9
0
AI/ ML & Data

AI 學習紀錄系列 第 9

Day 9: Stable Duiffsion 測試3

  • 分享至 

  • xImage
  •  

繼續玩 Stable Duiffsion XL。
https://huggingface.co/docs/diffusers/en/using-diffusers/sdxl

一樣先裝一裝需要的東西。

pip install diffusers
from diffusers import AutoPipelineForText2Image
import torch

先產一張圖。

pipeline = AutoPipelineForText2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", 
    torch_dtype=torch.float16, variant="fp16"
)
pipeline.enable_model_cpu_offload()
image = pipeline(
  "A majestic lion jumping from a big stone at night"
).images[0]
image

https://ithelp.ithome.com.tw/upload/images/20240825/20168318AQDcQIB2yo.png

接下來我們試試看模型說的 refiner 方式,就是 Stable Diffusion XL 的特色,可以增加圖像精細度的架構。
分別把 base、refiner 讀進來。

from diffusers import DiffusionPipeline

base = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", 
    torch_dtype=torch.float16, 
    variant="fp16", 
    use_safetensors=True
).to("cuda")

refiner = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-refiner-1.0",
    text_encoder_2=base.text_encoder_2,
    vae=base.vae,
    torch_dtype=torch.float16,
    use_safetensors=True,
    variant="fp16",
).to("cuda")

跟剛剛同樣的 prompt,看看產出的效果。

prompt = "A majestic lion jumping from a big stone at night"

image = base(
    prompt=prompt,
    num_inference_steps=40,
    denoising_end=0.8,
    output_type="latent",
).images
image = refiner(
    prompt=prompt,
    num_inference_steps=40,
    denoising_start=0.8,
    image=image,
).images[0]
image

https://ithelp.ithome.com.tw/upload/images/20240825/201683183IbNpqH1Xl.png

這次多給了幾個參數,num_inference_steps、denoising_end、denoising_star。num_inference_steps 是去除雜訊的步數,一般調越高影像品質越好,但同時運算速度越慢。
denoising_end=0.8 是在 base 階段的 step 的前 80% 執行 denoising,denoising_star=0.8 是在 refiner 階段的 step 的後 20% 執行 denoising。
不過我還沒看到跳過幾個 step 不去 denoising 的原因,之後確定了再來補上。
output_type 給的是 latent 而不是 PIL,沒有還原成圖片。

這個流程實際上就是先生成圖,然後將圖丟給 refiner 去加細節,所以其實也可以這樣。

from diffusers import AutoPipelineForImage2Image
base = AutoPipelineForText2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", 
    torch_dtype=torch.float16, 
    variant="fp16"
).to("cuda")

refiner = AutoPipelineForImage2Image.from_pretrained(
    "stabilityai/stable-diffusion-xl-refiner-1.0", 
    torch_dtype=torch.float16, 
    variant="fp16", 
    use_safetensors=True
).to("cuda")

然後生圖。

prompt = "A majestic lion jumping from a big stone at night"
image_base = base(prompt=prompt, output_type="latent").images[0]
image = refiner(prompt=prompt, image=image_base[None, :]).images[0]
image

https://ithelp.ithome.com.tw/upload/images/20240825/20168318BLV4kLxMM0.png

不過我也很疑惑,這邊 output_type 設為 latent 的原因應該只是想要減少一次 decode的過程吧,還是說要再將 image 壓到 latent 會讓效果變差呢?
所以試了一下。

from diffusers.utils import make_image_grid
prompt = "A majestic lion jumping from a big stone at night"
image_base = base(prompt=prompt).images[0]
image = refiner(prompt=prompt, image=image_base).images[0]
make_image_grid([image_base, image], rows=1, cols=2)

好吧,可能會。
https://ithelp.ithome.com.tw/upload/images/20240825/2016831817IvSLJobP.png

最後是,這個方法也可以直接去做 Inpaint,讀取模型的方式又變了,之後再討論,總之先照著官方來。

from diffusers import StableDiffusionXLInpaintPipeline
from diffusers.utils import load_image

base = StableDiffusionXLInpaintPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")

refiner = StableDiffusionXLInpaintPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-refiner-1.0",
    text_encoder_2=base.text_encoder_2,
    vae=base.vae,
    torch_dtype=torch.float16,
    use_safetensors=True,
    variant="fp16",
).to("cuda")

把圖讀進來。

img_url = "https://raw.githubusercontent.com/CompVis/latent-diffusion/main/data/inpainting_examples/overture-creations-5sI6fQgYIuo.png"
mask_url = "https://raw.githubusercontent.com/CompVis/latent-diffusion/main/data/inpainting_examples/overture-creations-5sI6fQgYIuo_mask.png"
init_image = load_image(img_url)
mask_image = load_image(mask_url)
make_image_grid([init_image, mask_image], rows=1, cols=2)

https://ithelp.ithome.com.tw/upload/images/20240825/20168318JRIsJinV7O.png

最後下 prompt 產圖。成品有點一言難盡,但至少是完成任務了。

prompt = "A majestic tiger sitting on a bench"
num_inference_steps = 75
high_noise_frac = 0.7

image = base(
    prompt=prompt,
    image=init_image,
    mask_image=mask_image,
    num_inference_steps=num_inference_steps,
    denoising_end=high_noise_frac,
    output_type="latent",
).images
image = refiner(
    prompt=prompt,
    image=image,
    mask_image=mask_image,
    num_inference_steps=num_inference_steps,
    denoising_start=high_noise_frac,
).images[0]
image

https://ithelp.ithome.com.tw/upload/images/20240825/20168318r8JKsSGnaW.png

這整個過程原本我是用 T4 GPU,後面因為重複測試,有時候 GPU memory 會被我用爆,嫌麻煩就改用 L4 GPU,供參考。


上一篇
Day 8: Stable Duiffsion 測試2
下一篇
DAY 10: 生成影片
系列文
AI 學習紀錄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言